package ca.jsbr.as2js_lib.display.canvas 
{
	import ca.jsbr.as2js_lib.event.EventDispatcher;
	import ca.jsbr.as2js_lib.event.MouseJSEvent;
	import ca.jsbr.as2js_lib.utils.geom.Rect;
	import ca.jsbr.as2js_lib.utils.MouseManager;
	import js.element.canvas.CanvasRenderingContext2D;
	import js.event.MouseJSEvent;
	/**
	 * ...
	 * @author jsbr [me@jsbr.ca]
	 */
	public class View extends EventDispatcher
	{
		static public const UP:int = 0;
		static public const OVER:int = 1;
		static public const DOWN:int = 2;
		static public const DISABLE:int = 3;
		
		
		protected var _state:int;
		
		protected var _x:Number=0;
		protected var _y:Number=0;
		protected var _width:Number=0;
		protected var _height:Number=0;
		protected var _parent:Node2D;
		protected var _visible:Boolean;
		protected var _name:String;
		protected var _mouseMoveEnable:Boolean;
		protected var _mouseDownEnable:Boolean;
		protected var _mouseUpEnable:Boolean;
		protected var _mouseClickEnable:Boolean;
		private var _mouseEnable:Boolean = true;
		private var _mouse:MouseManager;
		protected var _alpha:Number = 1;
		
		
		public function View() 
		{
			_visible = true;
			_mouse = MouseManager.getInstance();
			_mouseMoveEnable = false;
			_mouseDownEnable = false;
			_mouseUpEnable = false;
			_mouseClickEnable = false;
		}
		//TODO Suprimé l'évenement, mettre dans render puis suivre la souris et les boutons
		override public function addEventListener(evtType:String, listener:Function):void 
		{
			if (!_mouseMoveEnable && (evtType == MouseJSEvent.MOUSE_MOVE || evtType == MouseJSEvent.MOUSE_OVER || evtType == MouseJSEvent.MOUSE_OUT))
			{
				_mouseMoveEnable = true;
			}
			else if (!_mouseDownEnable && evtType == MouseJSEvent.MOUSE_DOWN)
			{
				_mouseDownEnable = true;
			}
			else if (!_mouseUpEnable && evtType == MouseJSEvent.MOUSE_UP)
			{
				_mouseUpEnable = true;
			}
			else if (!_mouseClickEnable && evtType == MouseJSEvent.MOUSE_CLICK)
			{
				_mouseClickEnable = true;
			}
			super.addEventListener(evtType, listener);
		}
		
		override public function removeEventListener(evtType:String, listener:Function = null):void 
		{
	
			if (!_mouseMoveEnable && (evtType == MouseJSEvent.MOUSE_MOVE || evtType == MouseJSEvent.MOUSE_OVER || evtType == MouseJSEvent.MOUSE_OUT))
			{
				_mouseMoveEnable = false;
			}
			else if (!_mouseDownEnable && evtType == MouseJSEvent.MOUSE_DOWN)
			{
				_mouseDownEnable = false;
			}
			else if (!_mouseUpEnable && evtType == MouseJSEvent.MOUSE_UP)
			{
				_mouseUpEnable = false;
			}
			else if (!_mouseClickEnable && evtType == MouseJSEvent.MOUSE_CLICK)
			{
				_mouseClickEnable = false;
			}
			super.removeEventListener(evtType, listener);
		}
		
		public function get stage():CanvasStage
		{
			if(_parent)
				return _parent.stage
			return null;
		}
		
		public function hitTestPoint(x:Number, y:Number, alpha:Number = 0):Boolean
		{
			if(!stage)
				return false;
			return x > stageX && y > stageY && x < stageX + width && y < stageY + height;
		}
		
		/**
		 * TODO à revoir
		 */
		public function preRender(context:CanvasRenderingContext2D):void
		{
			if(_alpha!=1)
				context.globalAlpha = _alpha;
			if (_mouseEnable && _mouse.action && (_mouseClickEnable || _mouseDownEnable || _mouseMoveEnable || _mouseUpEnable))
			{
				var mx:Number = _mouse.stageMouse.x
				var my:Number = _mouse.stageMouse.y;
				var hit:Boolean;
				var hitDetect:Boolean = false;
				if (_mouseClickEnable && _mouse.click) {
					hit = hitTestPoint(mx, my);
					hitDetect = true;
					if(hit)
						dispatchEvent(new MouseJSEvent(MouseJSEvent.MOUSE_CLICK, mx, my));
				}
				if (_mouseDownEnable && _mouse.down && hit) {
					if (!hitDetect) {
						hit = hitTestPoint(mx, my);
						hitDetect = true;
					}
					if(hit)
						dispatchEvent(new MouseJSEvent(MouseJSEvent.MOUSE_DOWN, mx, my));
				}
				if (_mouseUpEnable && _mouse.up && hit)
				{
					if (!hitDetect) {
						hit = hitTestPoint(mx, my);
						hitDetect = true;
					}
					if(hit)
						hit = hitTestPoint(mx, my);
					hitDetect = true;
					dispatchEvent(new MouseJSEvent(MouseJSEvent.MOUSE_DOWN, mx, my));
				}
				if (_mouseMoveEnable)
				{
					if (!hitDetect) {
						hit = hitTestPoint(mx, my);
						hitDetect = true;
					}
					if (_state==UP && hit)
					{
						_state = OVER;
						dispatchEvent(new MouseJSEvent(MouseJSEvent.MOUSE_OVER, mx, my));
					}
					else if (_state==OVER && !hit)
					{
						_state = UP;
						dispatchEvent(new MouseJSEvent(MouseJSEvent.MOUSE_OUT, mx, my));
					}
					//dispatchEvent(new MouseJSEvent(MouseJSEvent.MOUSE_MOVE, mx, my));
				}
			}
		}
		
		public function render(ctx:CanvasRenderingContext2D,view:Rect=null):void
		{

		}
		
		public function postRender(context:CanvasRenderingContext2D):void
		{
			if(_alpha!=1)
				context.globalAlpha = 1;
		}
		
		public function get stageX():Number
		{
			return parent.stageX + x;
		}
		
		public function get stageY():Number
		{
			return parent.stageY + y;
		}
		
		public function get x():Number
		{
			return _x;
		}
		
		public function set x(value:Number):void 
		{
			_x = value;
		}
		
		public function get y():Number 
		{
			return _y;
		}
		
		public function set y(value:Number):void 
		{
			_y = value;
		}
		
		public function get width():Number 
		{
			return _width;
		}
		
		public function set width(value:Number):void 
		{
			_width = value;
		}
		
		public function get height():Number 
		{
			return _height;
		}
		
		public function set height(value:Number):void 
		{
			_height = value;
		}		
		
		public function get parent():Node2D 
		{
			return _parent;
		}
		
		public function set parent(value:Node2D):void 
		{
			_parent = value;
		}
		
		public function get visible():Boolean 
		{
			return _visible;
		}
		
		public function set visible(value:Boolean):void 
		{
			_visible = value;
		}
		
		public function get state():int 
		{
			return _state;
		}
		
		public function set state(value:int):void 
		{
			_state = value;
		}
		
		public function get mouseEnable():Boolean 
		{
			return _mouseEnable;
		}
		
		public function set mouseEnable(value:Boolean):void 
		{
			_mouseEnable = value;
		}
		
		public function get name():String 
		{
			return _name;
		}
		
		public function set name(value:String):void 
		{
			_name = value;
		}
		
		public function get alpha():Number 
		{
			return _alpha;
		}
		
		public function set alpha(value:Number):void 
		{
			_alpha = value;
		}
		
		public function destroy():void
		{
			mouseEnable = false;
		}
	}

}